/**
 * Aby命名空间
 * 
 * @author xjlong
 * @version 1.0.0
 * @data 2010-7-2 12:48
 * @type
 */
var aby = Aby = {
	version : '1.0.0.0',
	author : 'xjlong',
	jsErrorCallBack : null,
	showErrorMessage : true,
	clearError : false,
	BLANK_IMAGE_URL: " resources/images/s.gif",
	BLANK_IMG_URL: "resources/images/s.gif",
	maskMsg: '正在加载...',
	userAgent : window.navigator.userAgent,
	isIE : function() {
		if (this.userAgent.indexOf("MSIE"))
			return true;
		else
			return false;
	},
	util : {},
	ui : {},
	ext : {},
	mask : {},
	os:{},
	elCache: {
	    menu : []
	}
};

/**
 * 加载文件
 * 
 * @param {}
 *            url 文件地址
 * @param {}
 *            fn 回调函数
 */
Aby.util.loadFile = function(url, fn) {
	Aby.loadFileComplete = false;
	var doc = document.getElementsByTagName('head')[0];
	var js = null;
	if (url && url.substring(url.length - 3).toLowerCase() == ".js") {
		js = document.createElement('script');
		js.setAttribute('type', 'text/javascript');
		js.setAttribute('src', Aby.loadFileNoCache ? Aby.urlAppend(url,
						"nocache=" + new Date().getTime()) : url);
		js.setAttribute('originalUrl', url);
		doc.appendChild(js);
	} else {
		js = document.createElement('link');
		js.setAttribute('type', 'text/css');
		js.setAttribute("rel", "stylesheet");
		js.setAttribute('originalUrl', url);
		js.setAttribute('href', Aby.loadFileNoCache ? Aby.urlAppend(url,
						"nocache=" + new Date().getTime()) : url);
		doc.appendChild(js);
	}
	var flag = false;
	try {
		if (!Aby.isIE) {
			js.onload = function() {
				fn(js);
			}
		} else {
			js.onreadystatechange = function() {
				if (js.readyState == 'loaded' || js.readyState == 'complete') {
					if (typeof fn == "function")
						fn(js);
				}
			}
		}
	} catch (e) {
	}
};

Aby.apply = function(o, c, defaults) {
	if (defaults) {
		Aby.apply(o, defaults);
	}
	if (o && c && typeof c == 'object') {
		for (var p in c) {
			o[p] = c[p];
		}
	}
	return o;
};

(function() {
	var idSeed = 0, toString = Object.prototype.toString, ua = navigator.userAgent
			.toLowerCase(), check = function(r) {
		return r.test(ua);
	}, DOC = document, isStrict = DOC.compatMode == "CSS1Compat", isOpera = check(/opera/), isChrome = check(/\bchrome\b/), isWebKit = check(/webkit/), isSafari = !isChrome
			&& check(/safari/), isSafari2 = isSafari && check(/applewebkit\/4/), isSafari3 = isSafari
			&& check(/version\/3/), isSafari4 = isSafari && check(/version\/4/), isIE = !isOpera
			&& check(/msie/), isIE7 = isIE && check(/msie 7/), isIE8 = isIE
			&& check(/msie 8/), isIE6 = isIE && !isIE7 && !isIE8, isGecko = !isWebKit
			&& check(/gecko/), isGecko2 = isGecko && check(/rv:1\.8/), isGecko3 = isGecko
			&& check(/rv:1\.9/), isBorderBox = isIE && !isStrict, isWindows = check(/windows|win32/), isMac = check(/macintosh|mac os x/), isAir = check(/adobeair/), isLinux = check(/linux/), isSecure = /^https/i
			.test(window.location.protocol);

	if (isIE6) {
		try {
			DOC.execCommand("BackgroundImageCache", false, true);
		} catch (e) {
		}
	}

	Aby.apply(Aby, {
		SSL_SECURE_URL : isSecure && isIE ? 'javascript:""' : 'about:blank',
		isStrict : isStrict,
		isSecure : isSecure,
		isReady : false,
		enableGarbageCollector : true,
		enableListenerCollection : false,
		enableNestedListenerRemoval : false,
		USE_NATIVE_JSON : false,
		needFiles : ["javascript/aby/resources/css/aby.css"],
		laodedFile : [],
		libBasePath : "javascript/lib/",
		debug : true,
		loadFileComplete : false,
		loadedFileIndex : -1,
		loadFileNoCache : true,
		registCompleted : false,
		pageSize : 20,
		loadFileCallback : function(file) {
			var url = file.getAttribute("originalUrl").toLowerCase();
			var index = Aby.needFiles.indexOf(url);
			Aby.laodedFile.add(url);
			var fileCount = Aby.laodedFile.length;

			if (url.indexOf("ext-all") != -1 && url.indexOf(".css") == -1) {
				Aby.registCompleted = true;
				Aby.afterRegist();
			}
			if (Aby.isIE) {
				if (fileCount == Aby.needFiles.length) {
					Aby.loadFileComplete = true;
					Aby.afterLoadFile();
				} else {
					Aby.loadFileComplete = false;
				}
			} else {
			if (Aby.needFiles[Aby.needFiles.length - 1].toLowerCase() == url) {
					Aby.loadFileComplete = true;
					Aby.afterLoadFile();
	}
			}
		},
		afterLoadFile : function() {
			if (this.isFunction(this.ready))
				this.ready();

		},
		afterRegist : function() {
		},
		applyIf : function(o, c) {
			if (o) {
				for (var p in c) {
					if (!Aby.isDefined(o[p])) {
						o[p] = c[p];
					}
				}
			}
			return o;
		},
		/**
		 * 加载js 或者 css 文件
		 */
		needFileAdded : function(cb) {
			Aby.loadFileComplete = false;
			var files = Aby.needFiles;
			var index = Aby.loadedFileIndex;
			var len = files.length;
			if (len == index + 1) {
				return;
			} else {
				for (var i = index + 1; i < len; i++) {
					Aby.util.loadFile(files[i], Aby.loadFileCallback);
					index = i;
				}
			}
			Aby.loadedFileIndex = index;
		},

		initDefaults : function() {
			Aby.apply(Aby, Aby.defaults);
		},

		registComplete : function(fn) {
			var timer = null;
			if (Aby.registCompleted == true)
				clearTimeout(timer);
			else {
				timer = setInterval(function() {
							if (Aby.registCompleted == true)
								fn();
						}, 10);
			}
		},

		/**
		 * 加载完毕, 该方法无效
		 * 
		 * @param {}
		 *            fn
		 * @param {}
		 *            scope
		 * @param {}
		 *            options
		 */
		onReady : function(fn) {
			if (Aby.loadFileComplete == true) {
				setTimeout(fn, 10);
			} else {
				var timer = null;
				timer = setInterval(function() {
							if (Aby.loadFileComplete == true) {
								setTimeout(fn, 10);
								clearInterval(timer);
							}
						}, 10);
			}
		},

		id : function(el, prefix) {
			el = Aby.getDom(el, true) || {};
			if (!el.id) {
				el.id = (prefix || "ext-gen") + (++idSeed);
			}
			return el.id;
		},

		getDom : function(el, strict) {
			if (!el || !DOC) {
				return null;
			}
			if (el.dom) {
				return el.dom;
			} else {
				if (typeof el == 'string') {
					var e = DOC.getElementById(el);
					if (e && isIE && strict) {
						if (el == e.getAttribute('id')) {
							return e;
						} else {
							return null;
						}
					}
					return e;
				} else {
					return el;
				}
			}
		},

		getBody : function() {
			return Aby.get(DOC.body || DOC.documentElement);
		},

		/**
		 * 注册js
		 * 
		 * @param {Object}
		 *            type
		 */
		regist : function(type, cb, mask) {
			switch (type.toLowerCase()) {
				case "extjs" :
					this.registCompleted = false;
					var libBasePath = this.libBasePath;
					var css = "extjs/resources/css/ext-all.css";
					var base = "extjs/ext-base.js";
					var all = "extjs/ext-all.js";
					if (Aby.debug) {
						base = "extjs/ext-base-debug.js";
						all = "extjs/ext-all-debug.js";
					}
					Aby.needFiles.add(libBasePath + css);
					Aby.needFiles.add(libBasePath + base);
					Aby.needFiles.add(libBasePath + all);
					Aby.needFileAdded();
					break;
				case "jquery" :
					var libBasePath = this.libBasePath;
					var base = "jQuery/jquery-1.4.2.min.js";
					if (Aby.debug) {
						base = "jQuery/jquery-1.4.2.js";
					}
					Aby.needFiles.add(libBasePath + base);
					Aby.needFileAdded();
					break;
			}
		},

		getClientWidth : function(el) {
			if (Aby.isEmpty(el)) {
				return document.documentElement.clientWidth
			} else {
				return Aby.getDom(el).clientWidth;
			}
		},
		getclientHeight : function(el) {
			if (Aby.isEmpty(el)) {
				return document.documentElement.clientHeight
			} else {
				return Aby.getDom(el).clientHeight;
			}
		},

		showMask : function() {
			var wd = Aby.getClientWidth(), hg = Aby.getclientHeight();
			var div = document.createElement("div");
			var twrap = document.createElement("div");
			twrap.className = "aby-mask-text";
			twrap.style.top = hg / 2 - 30;
			twrap.style.left = wd / 2 - 30;
			twrap.appendChild(document.createTextNode(Aby.maskMsg));
			twrap.id = Aby.id();
			document.body.appendChild(twrap);
			document.body.appendChild(div);
			div.className = "aby-mask";
			div.style.width = wd;
			div.style.height = hg;
			div.id = Aby.id();
			Aby.elCache.pm = div;
			Aby.elCache.tm = twrap;
		},

		removeMask : function() {
			if (Aby.elCache.pm) {
				Aby.removeNode(Aby.elCache.pm);
			}
			if (Aby.elCache.tm) {
				Aby.removeNode(Aby.elCache.tm);
			}
		},

		removeNode : isIE && !isIE8 ? function() {
			var d;
			return function(n) {
				if (n && n.tagName != 'BODY') {
					d = d || DOC.createElement('div');
					d.appendChild(n);
					d.innerHTML = '';
					delete Aby.elCache[n.id];
				}
			}
		}() : function(n) {
			if (n && n.parentNode && n.tagName != 'BODY') {
				n.parentNode.removeChild(n);
				delete Aby.elCache[n.id];
			}
		},

		extend : function() {

			var io = function(o) {
				for (var m in o) {
					this[m] = o[m];
				}
			};
			var oc = Object.prototype.constructor;

			return function(sb, sp, overrides) {
				if (typeof sp == 'object') {
					overrides = sp;
					sp = sb;
					sb = overrides.constructor != oc
							? overrides.constructor
							: function() {
								sp.apply(this, arguments);
							};
				}
				var F = function() {
				}, sbp, spp = sp.prototype;

				F.prototype = spp;
				sbp = sb.prototype = new F();
				sbp.constructor = sb;
				sb.superclass = spp;
				if (spp.constructor == oc) {
					spp.constructor = sp;
				}
				sb.override = function(o) {
					Aby.override(sb, o);
				};
				sbp.superclass = sbp.supr = (function() {
					return spp;
				});
				sbp.override = io;
				Aby.override(sb, overrides);
				sb.extend = function(o) {
					return Aby.extend(sb, o);
				};
				return sb;
			};
		}(),

		destroy : function() {
			Aby.each(arguments, function(arg) {
						if (arg) {
							if (Aby.isArray(arg)) {
								this.destroy.apply(this, arg);
							} else if (typeof arg.destroy == 'function') {
								arg.destroy();
							} else if (arg.dom) {
								arg.remove();
							}
						}
					}, this);
		},

		destroyMembers : function(o, arg1, arg2, etc) {
			for (var i = 1, a = arguments, len = a.length; i < len; i++) {
				Aby.destroy(o[a[i]]);
				delete o[a[i]];
			}
		},

		override : function(origclass, overrides) {
			if (overrides) {
				var p = origclass.prototype;
				Aby.apply(p, overrides);
				if (Aby.isIE && overrides.hasOwnProperty('toString')) {
					p.toString = overrides.toString;
				}
			}
		},
		fireEvent : function(eventName, target, scope) {
			var dom = null;
            if(this.isString(target))
                dom = this.getDom(target);                
            else if(this.isElement(target))
                dom = target;
			if (this.isIE) {
				dom.fireEvent("on"+eventName);
			} else {
				var e = document.createEvent('MouseEvent');
				e.initEvent(eventName, false, true);
				dom.dispatchEvent(e);
			}
		},

		namespace : function() {
			var o, d;
			Aby.each(arguments, function(v) {
						d = v.split(".");
						o = window[d[0]] = window[d[0]] || {};
						Aby.each(d.slice(1), function(v2) {
									o = o[v2] = o[v2] || {};
								});
					});
			return o;
		},

		urlEncode : function(o, pre) {
			var empty, buf = [], e = encodeURIComponent;

			Aby.iterate(o, function(key, item) {
				empty = Aby.isEmpty(item);
				Aby.each(empty ? key : item, function(val) {
							buf
									.push(
											'&',
											e(key),
											'=',
											(!Aby.isEmpty(val) && (val != key || !empty))
													? (Aby.isDate(val)
															? Aby
																	.encode(val)
																	.replace(
																			/"/g,
																			'')
															: e(val))
													: '');
						});
			});
			if (!pre) {
				buf.shift();
				pre = '';
			}
			return pre + buf.join('');
		},

		urlDecode : function(string, overwrite) {
			if (Aby.isEmpty(string)) {
				return {};
			}
			var obj = {}, pairs = string.split('&'), d = decodeURIComponent, name, value;
			Aby.each(pairs, function(pair) {
						pair = pair.split('=');
						name = d(pair[0]);
						value = d(pair[1]);
						obj[name] = overwrite || !obj[name] ? value : []
								.concat(obj[name]).concat(value);
					});
			return obj;
		},

		urlAppend : function(url, s) {
			if (!Aby.isEmpty(s)) {
				return url + (url.indexOf('?') === -1 ? '?' : '&') + s;
			}
			return url;
		},

		toArray : function() {
			return isIE ? function(a, i, j, res) {
				res = [];
				for (var x = 0, len = a.length; x < len; x++) {
					res.push(a[x]);
				}
				return res.slice(i || 0, j || res.length);
			} : function(a, i, j) {
				return Array.prototype.slice.call(a, i || 0, j || a.length);
			}
		}(),

		isIterable : function(v) {

			if (Aby.isArray(v) || v.callee) {
				return true;
			}

			if (/NodeList|HTMLCollection/.test(toString.call(v))) {
				return true;
			}
			return ((typeof v.nextNode != 'undefined' || v.item) && Aby
					.isNumber(v.length));
		},

		each : function(array, fn, scope) {
			if (Aby.isEmpty(array, true)) {
				return;
			}
			if (!Aby.isIterable(array) || Aby.isPrimitive(array)) {
				array = [array];
			}
			for (var i = 0, len = array.length; i < len; i++) {
				if (fn.call(scope || array[i], array[i], i, array) === false) {
					return i;
				};
			}
		},

		isEmpty : function(v, allowBlank) {
			return v === null || v === undefined
					|| ((Aby.isArray(v) && !v.length))
					|| (!allowBlank ? v === '' : false);
		},

		isArray : function(v) {
			return toString.apply(v) === '[object Array]';
		},

		isDate : function(v) {
			return toString.apply(v) === '[object Date]';
		},

		isObject : function(v) {
			return !!v
					&& Object.prototype.toString.call(v) === '[object Object]';
		},

		isPrimitive : function(v) {
			return Aby.isString(v) || Aby.isNumber(v) || Aby.isBoolean(v);
		},

		isFunction : function(v) {
			return toString.apply(v) === '[object Function]';
		},

		isNumber : function(v) {
			return typeof v === 'number' && isFinite(v);
		},

		isString : function(v) {
			return typeof v === 'string';
		},

		isBoolean : function(v) {
			return typeof v === 'boolean';
		},

		isElement : function(v) {
			return v ? !!v.tagName : false;
		},

		isDefined : function(v) {
			return typeof v !== 'undefined';
		},

		isOpera : isOpera,

		isWebKit : isWebKit,

		isChrome : isChrome,

		isSafari : isSafari,

		isSafari3 : isSafari3,

		isSafari4 : isSafari4,

		isSafari2 : isSafari2,

		isIE : isIE,

		isIE6 : isIE6,

		isIE7 : isIE7,

		isIE8 : isIE8,

		isGecko : isGecko,

		isGecko2 : isGecko2,

		isGecko3 : isGecko3,

		isBorderBox : isBorderBox,

		isLinux : isLinux,

		isWindows : isWindows,

		isMac : isMac,

		isAir : isAir
	});
	Aby.ns = Aby.namespace;
})();

Aby.apply(Function.prototype, {
			/**
			 * 创建方法的拦截器
			 * 
			 * @param {Object}
			 *            fcn 方法名
			 * @param {Object}
			 *            scope 作用域
			 */
			createInterceptor : function(fcn, scope) {
				var method = this;
				return !Ext.isFunction(fcn) ? this : function() {
					var me = this, args = arguments;
					fcn.target = me;
					fcn.method = method;
					return (fcn.apply(scope || me || window, args) !== false)
							? method.apply(me || window, args)
							: null;
				};
			},
			/**
			 * 创建回调方法
			 */
			createCallback : function() {

				var args = arguments, method = this;
				return function() {
					return method.apply(window, args);
				};
			},
			/**
			 * 创建方法代理
			 * 
			 * @param {Object}
			 *            obj 代理对象
			 * @param {Object}
			 *            args 参数
			 * @param {Object}
			 *            appendArgs 是否可以添加参数
			 */
			createDelegate : function(obj, args, appendArgs) {
				var method = this;
				return function() {
					var callArgs = args || arguments;
					if (appendArgs === true) {
						callArgs = Array.prototype.slice.call(arguments, 0);
						callArgs = callArgs.concat(args);
					} else if (Aby.isNumber(appendArgs)) {
						callArgs = Array.prototype.slice.call(arguments, 0);
						var applyArgs = [appendArgs, 0].concat(args);
						Array.prototype.splice.apply(callArgs, applyArgs);
					}
					return method.apply(obj || window, callArgs);
				};
			},

			/**
			 * 延迟方法执行
			 * 
			 * @param {Object}
			 *            millis 延续毫秒数
			 * @param {Object}
			 *            obj 执行对象
			 * @param {Object}
			 *            args 参数
			 * @param {Object}
			 *            appendArgs 是否可以添加参数
			 */
			defer : function(millis, obj, args, appendArgs) {
				var fn = this.createDelegate(obj, args, appendArgs);
				if (millis > 0) {
					return setTimeout(fn, millis);
				}
				fn();
				return 0;
			}
		});

Aby.apply(Array.prototype, {
			/**
			 * 数组是否只有一个元素
			 * 
			 * @return {Boolean}
			 */
			isOne : function() {
				if (this.length == 1)
					return true;
				else
					return false;
			},
			/**
			 * 获得数组里field的值
			 * 
			 * @param {}
			 *            field
			 * @return 数组
			 */
			getFieldValues : function(field) {
				var arr = [];
				for (var i = 0; i < this.length; i++) {
					arr.push(this[i].get(field));
				}
				return arr;
			},
			/**
			 * 扩展数组的遍历方法
			 * 
			 * @param {}
			 *            fn
			 */
			each : function(fn) {
				if (typeof fn == 'function') {
					for (var i = 0; i < this.length; i++)
						fn(this[i]);
				}
},
			
            collect : function(field){
			    return this.getFieldValues(field);
			},
            to2D : function(){
                var r =[];
                this.each(function(i){
                    var a = [];
                    a.push(i);
                    r.push(a);
                });
                return r;
            },

			/**
			 * 扩展Array ，添加一个add方法
			 * 
			 * @param {Object}
			 *            item 要添加的项
			 * @param {Object}
			 *            onchange 回调函数
			 */
			add : function(item, onchange) {
				this.push(item);
				if (typeof onchange == "function") {
					onchange();
				}
			},

			indexOf : function(o, from) {
				var len = this.length;
				from = from || 0;
				from += (from < 0) ? len : 0;
				for (; from < len; ++from) {
					if (this[from] === o) {
						return from;
					}
				}
				return -1;
			},
			remove: function (o) {
			    var index = this.indexOf(o);
			    if (index != -1) {
			        this.splice(index, 1);
			    }
			    return this;
			},
            contains : function(char){
                return this.indexOf(char)>-1;
            }
		});

        Aby.apply(String.prototype,{
            contains: function (key) {
                return this.indexOf(key) > -1;
            },            
			startsWith : function(str, value){
				return str.match("^" + value) !== null;
			},
			endsWith : function(str, value){
				return str.match(value + "$") !== null;
			}
        });
(function() {
	if (Aby) {
		aby = Aby.apply(aby, Aby);
	}
})();
